<!-- 上传指纹文件 -->
<template>
  <div class="upload-block">
    <a-button v-if="uploadStatus === 'null'" type="link" class="icon-with-btn" :disabled="disabled" @click="onUploadClick">
      <i class="iconfont icon-upload-2-line"></i>
      上传
    </a-button>
    <a-button v-else-if="uploadStatus === 'uploading'" type="link" class="icon-with-btn" disabled> 上传中... </a-button>
    <div v-else-if="uploadStatus === 'uploaded'" class="uploaded-block">
      <span :title="fileObj.fileName">{{ fileObj.fileName }}</span>
      <a-button v-if="showUploadBtn" type="link" class="icon-only-btn" @click="onUploadClick">
        <i class="iconfont icon-upload-2-line"></i>
      </a-button>
      <a-button v-if="showDownloadBtn" type="link" class="icon-only-btn" @click="download">
        <i class="iconfont icon-download-2-line"></i>
      </a-button>
    </div>

    <input v-show="false" ref="fileRef" type="file" accept=".txt" @change="onChange" />
  </div>
</template>

<script lang="ts" setup>
  import { message } from 'ant-design-vue'
  import { countStrToBit } from 'g6-fn'
  import { computed, ref, watch } from 'vue'
  import { useRequest } from 'vue-request'

  import { fetchDownload } from '@/services/api'
  import { appApi } from '@/services/api'
  type UploadStatus = 'null' | 'uploading' | 'uploaded'

  export interface UploadRes {
    /**
     * 文件名称
     */
    fileName: string
    /**
     * 文件交互路径
     */
    fileUrl: string
    /**
     * 唯一标识，在创建应用时传回后端，用于查询可激活设备数
     */
    sign: string
    /**
     * 可激活设备数
     */
    totalActivateNum: number
  }

  export interface Props {
    appServeId?: string
    fileName?: string
    fileUrl?: string
    showUploadBtn?: boolean
    showDownloadBtn?: boolean
    disabled?: boolean
  }

  const props = withDefaults(defineProps<Props>(), {
    appServeId: '',
    showUploadBtn: true,
    showDownloadBtn: false,
    disabled: false
  })
  const emits = defineEmits(['uploadSuccess'])

  watch([() => props.fileName, () => props.fileUrl], () => {
    fileObj.value.fileName = props.fileName || ''
    fileObj.value.fileUrl = props.fileUrl || ''
  })

  const fileObj = ref<UploadRes>({
    sign: '',
    totalActivateNum: 0,
    fileUrl: props.fileUrl || '',
    fileName: props.fileName || ''
  })
  const fileRef = ref()
  const uploadStatus = computed<UploadStatus>(() => {
    if (loading.value) {
      return 'uploading'
    }
    if (fileObj.value.fileName) {
      return 'uploaded'
    }
    return 'null'
  })

  const { loading, runAsync: upload } = useRequest<any>(appApi.uploadFingerprint, {
    onSuccess: res => {
      console.log(res)
      fileObj.value = res.data
      console.log('file', fileObj.value)
      emits('uploadSuccess', fileObj.value)
    },
    onError: err => {
      console.log(err)
    },
    onAfter: () => {
      // 清空选择文件
      fileRef.value?.value && (fileRef.value.value = '')
    }
  })

  const onUploadClick = () => {
    fileRef.value?.click()
  }
  const download = () => {
    fetchDownload(fileObj.value.fileUrl, fileObj.value.fileName)
  }

  const onChange = async (e: Event) => {
    const target = e.target as HTMLInputElement
    let file = target.files?.[0]
    if (!file) return

    if (countStrToBit(file?.name) > 200) {
      message.error('文件名不可超过200字节')
      fileRef.value.value = '' //清除
      return
    }
    if (!file) return

    const params = {
      file: file,
      appServeId: props.appServeId,
      fileUrl: `/warehouse/${Date.now()}/${file.name}` // 上传文件的路径
    }
    if (params.appServeId === null) {
      Reflect.deleteProperty(params, 'appServeId')
    }
    await upload(params)
  }
</script>

<style lang="less" scoped>
  @import '@/styles/mixins.less';

  .upload-block {
    display: flex;
  }

  .uploaded-block {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;

    span {
      max-width: 70%;
      .elliptical-1();
    }
  }
</style>
